使用裁剪节点实现蒙版效果
在游戏开发和图形渲染中,蒙版效果是一种常见的技术,用于控制图像或场景的可见区域。在 Dora SSR 中,我们可以使用 ClipNode
类轻松实现各种蒙版效果。本教程将通过示例代码,指导您如何使用 ClipNode
来实现基于形状和图像的蒙版效果。
1. 什么是 ClipNode
ClipNode
是 Dora SSR 中的一个场景节点类,用于设置裁剪蒙版,从而控制子节点的可见区域。通过指定一个蒙版节点(stencil
),ClipNode
会根据蒙版的形状或透明度来裁剪其子节点的渲染内容。
1.1 ClipNode 的主要属性
- stencil: 定义裁剪形状的蒙版节点。
- alphaThreshold: 生效的用于裁剪的蒙版像素的 alpha 阈值(0 到 1 之间)。只有当蒙版像素的 alpha 值大于该阈值时,裁剪才会生效。
- inverted: 是否翻转裁剪区域。当设置为
true
时,裁剪区域和非裁剪区域互换。
2. 示例 A:使用任意形状作为蒙版
在第一个示例中,我们将使用一个五角星形状作为蒙版,裁剪一个动画模型的显示区域。
2.1 步骤解析
- 创建五角星形状的顶点数据
- Lua
- Teal
- TypeScript
- YueScript
local function StarVertices(radius, line)
-- 计算五角星的顶点坐标
local a = math.rad(36)
local c = math.rad(72)
local f = math.sin(a) * math.tan(c) + math.cos(a)
local R = radius
local r = R / f
local vecs = {}
local count = 1
for i = 9, line and -1 or 0, -1 do
local angle = i * a
local cr = i % 2 == 1 and r or R
vecs[count] = Vec2(cr * math.sin(angle), cr * math.cos(angle))
count = count + 1
end
-- 返回顶点数组
return vecs
end
local function StarVertices(radius: number, line: integer): {Vec2.Type}
-- 计算五角星的顶点坐标
local a = math.rad(36)
local c = math.rad(72)
local f = math.sin(a) * math.tan(c) + math.cos(a)
local R = radius
local r = R / f
local vecs: {Vec2.Type} = {}
local count = 1
for i = 9, line and -1 or 0, -1 do
local angle = i * a
local cr = i % 2 == 1 and r or R
vecs[count] = Vec2(cr * math.sin(angle), cr * math.cos(angle))
count = count + 1
end
-- 返回顶点数组
return vecs
end
function StarVertices(radius: number, line: number) {
// 计算五角星的顶点坐标
const a = math.rad(36);
const c = math.rad(72);
const f = math.sin(a) * math.tan(c) + math.cos(a);
const R = radius;
const r = R / f;
const vecs: Vec2.Type[] = []
for (let i = 9; line ? -1 : 0; i--) {
const angle = i * a;
const cr = i % 2 == 1 ? r : R
vecs.push(Vec2(cr * math.sin(angle), cr * math.cos(angle)));
}
// 返回顶点数组
return vecs;
}
StarVertices = (radius, line) ->
-- 计算五角星的顶点坐标
a = math.rad 36
c = math.rad 72
f = math.sin(a) * math.tan(c) + math.cos a
R = radius
r = R / f
vecs = []
for i = 9, line and -1 or 0, -1
angle = i * a
cr = i % 2 == 1 and r or R
vecs[] = Vec2 cr * math.sin(angle), cr * math.cos angle
-- 返回顶点数组
vecs
- 绘制蒙版形状
- Lua
- Teal
- TypeScript
- YueScript
local maskA = DrawNode()
maskA:drawPolygon(StarVertices(160, false))
local maskA = DrawNode()
maskA:drawPolygon(StarVertices(160, false))
const maskA = DrawNode();
maskA.drawPolygon(StarVertices(160, false));
maskA = DrawNode()
maskA.drawPolygon StarVertices(160, false)
这里,我们使用 DrawNode
绘制一个五角星形状,作为蒙版节点。
- 创建动画模型
- Lua
- Teal
- TypeScript
- YueScript
local targetA = Model("Model/xiaoli.model")
targetA.look = "happy"
targetA.fliped = true
-- 设置模型的动画和移动路径
targetA:play("walk", true)
targetA:runAction(
Sequence(
X(1.5, -200, 200), Event("Turn"),
X(1.5, 200, -200), Event("Turn")
), true
)
targetA:slot("Turn", function()
targetA.fliped = not targetA.fliped
end)
local targetA = Model("Model/xiaoli.model")
if not targetA is nil then
targetA.look = "happy"
targetA.fliped = true
-- 设置模型的动画和移动路径
targetA:play("walk", true)
targetA:runAction(
Sequence(
X(1.5, -200, 200), Event("Turn"),
X(1.5, 200, -200), Event("Turn")
), true
)
targetA:slot("Turn", function()
targetA.fliped = not targetA.fliped
end)
end
const targetA = Model("Model/xiaoli.model");
if (targetA) {
targetA.look = "happy";
targetA.fliped = true;
// 设置模型的动画和移动路径
targetA.play("walk", true);
targetA.runAction(
Sequence(
X(1.5, -200, 200), Event("Turn"),
X(1.5, 200, -200), Event("Turn")
), true
);
targetA.slot("Turn", () => {
targetA.fliped = !targetA.fliped;
});
}
targetA = with Model "Model/xiaoli.model"
.look = "happy"
.fliped = true
-- 设置模型的动画和移动路径
.play "walk", true
\runAction Sequence(
X 1.5, -200, 200, Event "Turn",
X 1.5, 200, -200, Event "Turn"
), true
\slot "Turn", ->
targetA.fliped = not targetA.fliped
- 创建 ClipNode 并添加子节点
- Lua
- Teal
- TypeScript
- YueScript
local clipNodeA = ClipNode(maskA)
clipNodeA:addChild(targetA)
clipNodeA.inverted = true
local clipNodeA = ClipNode(maskA)
clipNodeA:addChild(targetA)
clipNodeA.inverted = true
const clipNodeA = ClipNode(maskA);
clipNodeA.addChild(targetA);
clipNodeA.inverted = true;
clipNodeA = with ClipNode maskA
\addChild targetA
.inverted = true
我们将蒙版节点 maskA
传递给 ClipNode
,并将动画模型 targetA
添加为其子节点。
- 添加到场景中
- Lua
- Teal
- TypeScript
- YueScript
local exampleA = Node()
exampleA:addChild(clipNodeA)
local exampleA = Node()
exampleA:addChild(clipNodeA)
const exampleA = Node();
exampleA.addChild(clipNodeA);
exampleA = with Node!
\addChild clipNodeA